package com.nifostasky.bloomfilter;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * redisson 布隆过滤器实现
 *
 * @author ludangxin
 * @date 2021/8/16
 */
@Slf4j
@RestController
@RequestMapping("bloomFilter")
@RequiredArgsConstructor
public class BloomFilterWithRedisson {
    private final RedissonClient redissonClient;

    /**
     * 预计要插入元素个数
     */
    private static final long SIZE = 1000000L;
    /**
     * 误判率
     */
    private static final double FPP = 0.01;

    /**
     * 自定义布隆过滤器的 key
     */
    private static final String BLOOM_FILTER_KEY = "bloomFilter";

    /**
     * 向布隆过滤器中添加数据, 模拟向布隆过滤器中添加10亿个数据
     */
    @GetMapping("filter")
    public void filter() {
        // 获取布隆过滤器
        RBloomFilter<Integer> bloomFilter = redissonClient.getBloomFilter(BLOOM_FILTER_KEY);
        // 初始化，容量为100万， 误判率为0.01
        bloomFilter.tryInit(SIZE, FPP);
        // 模拟向布隆过滤器中添加100万个数据
        for (int i = 0; i < SIZE; i++) {
            bloomFilter.add(i);
        }
        int count = 0;
        // 过滤判断
        for (int i = 1000000; i < 3000000; i++) {
            if (bloomFilter.contains(i)) {
                count++;
                log.info(i + "误判了");
            }
        }
        log.info("size:" + bloomFilter.getSize());
        log.info("总共的误判数:" + count);
    }
}
